﻿using Swift;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace SCM
{
    public class ReplayUtils
    {
        // 反序列化一个录像
        public static List<KeyValuePair<string, IReadableBuffer>> ReadReplay(IReadableBuffer reader)
        {
            string lastMsgTitle = null;
            byte[] lastMsgData = null;
            var msgs = new List<KeyValuePair<string, IReadableBuffer>>();
            var cnt = reader.ReadInt();
            FC.For(cnt, (i) =>
            {
                // 这里生成 msg 必须用网络字节序，因为这里的数据等同于是直接伪装成了网络上的消息，
                // 对 Room4Client 来说是一致读取的

                var sameAsLastOne = reader.ReadBool();
                if (!sameAsLastOne)
                {
                    var msgTitle = reader.ReadString();
                    var msgLen = reader.ReadInt();
                    var msgBody = reader.ReadBytes(msgLen);
                    msgs.Add(new KeyValuePair<string, IReadableBuffer>(msgTitle, new RingBuffer(true, true, msgBody)));

                    lastMsgTitle = msgTitle;
                    lastMsgData = msgBody;
                }
                else
                    msgs.Add(new KeyValuePair<string, IReadableBuffer>(lastMsgTitle, new RingBuffer(true, true, lastMsgData)));
            });

            return msgs;
        }

        // 序列化一个录像
        public static void WriteReplay(List<KeyValuePair<string, IReadableBuffer>> msgs, IWriteableBuffer writer)
        {
            string lastMsgTitle = null;
            byte[] lastMsgData = null;

            var cnt = msgs.Count;
            writer.Write(cnt);
            foreach (var msg in msgs)
            {
                var title = msg.Key;
                var body = msg.Value;
                var len = body.Available;
                var msgData = body.PeekBytes(len);

                if (title == lastMsgTitle && AllSame(lastMsgData, msgData))
                    writer.Write(true);
                else
                {
                    writer.Write(false);
                    writer.Write(title);
                    writer.Write(len);
                    writer.Write(msgData);

                    lastMsgTitle = msg.Key;
                    lastMsgData = msgData;
                }
            }
        }

        static bool AllSame(byte[] d1, byte[] d2)
        {
            if (d1 == d2)
                return true;
            else if (d1.Length != d2.Length)
                return false;

            var n = d1.Length;
            for (var i = 0; i < n; i++)
            {
                if (d1[i] != d2[1])
                    return false;
            }

            return true;
        }
    }
}